package com.itwk.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itwk.common.constant.ProductConstant;
import com.itwk.common.utils.PageUtils;
import com.itwk.common.utils.Query;
import com.itwk.gulimall.product.dao.PmsAttrAttrgroupRelationDao;
import com.itwk.gulimall.product.dao.PmsAttrDao;
import com.itwk.gulimall.product.dao.PmsAttrGroupDao;
import com.itwk.gulimall.product.entity.PmsAttrAttrgroupRelationEntity;
import com.itwk.gulimall.product.entity.PmsAttrEntity;
import com.itwk.gulimall.product.entity.PmsAttrGroupEntity;
import com.itwk.gulimall.product.entity.PmsCategoryEntity;
import com.itwk.gulimall.product.service.PmsAttrAttrgroupRelationService;
import com.itwk.gulimall.product.service.PmsAttrGroupService;
import com.itwk.gulimall.product.service.PmsCategoryService;
import com.itwk.gulimall.product.vo.AttrGroupRelation;
import com.itwk.gulimall.product.vo.AttrGroupWithAttrsVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service("pmsAttrGroupService")
public class PmsAttrGroupServiceImpl extends ServiceImpl<PmsAttrGroupDao, PmsAttrGroupEntity> implements PmsAttrGroupService {
    @Autowired
    private PmsCategoryService categoryService;
    @Autowired
    private PmsAttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Autowired
    private PmsAttrDao pmsAttrDao;
    @Autowired
    private PmsAttrAttrgroupRelationService relationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PmsAttrGroupEntity> page = this.page(
                new Query<PmsAttrGroupEntity>().getPage(params),
                new QueryWrapper<PmsAttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    //实现封装条件，根据分类查询品牌，如果没有点击分类，前端默认赋值为0 ，0就查询所有，也要取出map中的检索条件key
    @Override
    public PageUtils queryCategoryPage(Map<String, Object> params, Long catId) {
        //取出检索条件
        String key = (String)params.get("key");
        QueryWrapper<PmsAttrGroupEntity> queryWrapper = new QueryWrapper<>();
        IPage<PmsAttrGroupEntity> iPage = new Query<PmsAttrGroupEntity>().getPage(params);

        if(!StringUtils.isEmpty(key)){
             queryWrapper.eq("attr_group_id", key).or().like("attr_group_name", key). or().like("descript", key);
         }

        if(catId==0){
            //没有指定分类id,但有检索条件
                IPage<PmsAttrGroupEntity> page = baseMapper.selectPage(iPage, queryWrapper );
                       return new PageUtils(page);
        }else{
            //有分类id
            IPage<PmsAttrGroupEntity> page = baseMapper.selectPage(iPage,queryWrapper.and((wrapper)->{
                    wrapper.eq("catelog_id", catId);
            }));
            return new PageUtils(page);
        }

    }

    @Override  //分组信息的回显查询
    public PmsAttrGroupEntity getByIdWithCategory(Long attrGroupId) {
        PmsAttrGroupEntity pmsAttrGroupEntity = baseMapper.selectById(attrGroupId);
        Long catelogId = pmsAttrGroupEntity.getCatelogId();
        List<Long> paths = new ArrayList<>();
        getPath(catelogId,paths);
        Collections.reverse(paths);
        Long[] categoryPath = paths.toArray(new Long[0]);
        pmsAttrGroupEntity.setCatelogPath(categoryPath);

        return pmsAttrGroupEntity;
    }

    public List<Long> getPath(Long id,List<Long> paths){
            paths.add(id);  //先添加当前的节点
        PmsCategoryEntity category = categoryService.getById(id);
        if(category.getParentCid()!=0){
            //有父级分类，开始递归递归
              getPath(category.getParentCid(),paths);
        }

        return paths;
    }
  //分组信息的基本属性关联查询
    @Override
    public List<PmsAttrEntity> getAttrgoupRelation(Long attrgroupId) {
     //根据分组ID查询关联表中基本属性的ID集合，再根据id查询基本属性的值
        List<PmsAttrAttrgroupRelationEntity> groupRelations = attrAttrgroupRelationDao.selectList(new QueryWrapper<PmsAttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));

        List<Long> attrIds = groupRelations.stream().map((relation -> {
            return relation.getAttrId();
        })).collect(Collectors.toList());

        if(attrIds!=null&&attrIds.size()>0){

          return   pmsAttrDao.selectBatchIds(attrIds);

        }

        return null;
    }
    //删除分组下的属性关联
    @Override
    public void deleteRelation(AttrGroupRelation[] relations) {
        //由于是删除分组下的关联关系，所以分组不要操作，只需删除关联表中的对应关联关系，需要从分组和属性ID定位删除，且可能是集合，需要遍历动态sql
        //规范：接收用vo操作用
        List<Long> attrIds = Arrays.stream(relations).map((relation) -> {
            return relation.getAttrId();
        }).collect(Collectors.toList());
        Long attrGroupId = relations[0].getAttrGroupId();
        baseMapper.deleteRelation(attrIds,attrGroupId);

    }

    //分组信息中新建关联关系前需要查询当前没有被关联的属性
    @Override
    public PageUtils getNoGroupAttr(Map<String, Object> params,Long attrGroupId) {
        //通过当前的分组id 查询当前的分类id  ，新建关联必须为统一分类下的，再查询当前分类下的所有分组id，通过分组id再关联表中把所有已被关联的属性attr_id拿到，排除这部分就是未被关联的。
        PmsAttrGroupEntity groupEntity = baseMapper.selectById(attrGroupId);
        //取得当前分组所属分类下所有的分组集合
        List<PmsAttrGroupEntity> groupEntitys = baseMapper.selectList(new QueryWrapper<PmsAttrGroupEntity>().eq("catelog_id", groupEntity.getCatelogId()));
        //遍历取出所有分组的ID
        List<Long> groupIds = groupEntitys.stream().map((group) -> {
            return group.getAttrGroupId();
        }).collect(Collectors.toList());
        //关联表查询所有分组下的已被关联的属性，遍历取出ID集合

            List<PmsAttrAttrgroupRelationEntity> attrRelations = attrAttrgroupRelationDao.selectList(new QueryWrapper<PmsAttrAttrgroupRelationEntity>().in("attr_group_id", groupIds));
            //遍历取出已经被关联的属性ID
            List<Long> attrIds = attrRelations.stream().map(relation -> {
                return relation.getAttrId();
            }).collect(Collectors.toList());
             QueryWrapper<PmsAttrEntity> wrapper = new QueryWrapper<PmsAttrEntity>().eq("catelog_id", groupEntity.getCatelogId()).eq("attr_type", ProductConstant.ATTR_TYPE_BASE.getCode());   //结果必须为当前分类下的属性且不为销售属性
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            wrapper.like("attr_name", key);    //拼接查询条件
        }

        IPage<PmsAttrEntity> iPage = new Query<PmsAttrEntity>().getPage(params);

        if(attrIds!=null&&attrIds.size()>0){
                     //查询没有被包含的属性
            IPage<PmsAttrEntity> page = pmsAttrDao.selectPage(iPage, wrapper.notIn("attr_id", attrIds));
            return new PageUtils(page);

        }

        IPage<PmsAttrEntity> page = pmsAttrDao.selectPage(iPage, wrapper);

        return new PageUtils(page);
    }

    @Override
    public void saveRelation(AttrGroupRelation[] relation) {
        //使用批量保存方法
        List<PmsAttrAttrgroupRelationEntity> relations = Arrays.stream(relation).map(relationEntity -> {
            PmsAttrAttrgroupRelationEntity attrgroupRelationEntity = new PmsAttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(relationEntity, attrgroupRelationEntity);
            return attrgroupRelationEntity;
        }).collect(Collectors.toList());

        relationService.saveBatch(relations);

    }
   // 用于查询发布商品时的所选分类下的属性组与组下关联的基本属性
    @Override
    public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrs(Long catelogId) {
        //根据分类id查询分组表，取得所有的分组信息，再用分组的id 去关联表取得所有属性的id 取出 基本属性
        List<PmsAttrGroupEntity> attrGroups = baseMapper.selectList(new QueryWrapper<PmsAttrGroupEntity>().eq("catelog_id", catelogId));

        List<AttrGroupWithAttrsVo> attrs = attrGroups.stream().map(attrGroup -> {
            AttrGroupWithAttrsVo attrGroupWithAttrsVo = new AttrGroupWithAttrsVo();
            BeanUtils.copyProperties(attrGroup, attrGroupWithAttrsVo);
            List<PmsAttrAttrgroupRelationEntity> relations = attrAttrgroupRelationDao.selectList(new QueryWrapper<PmsAttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroup.getAttrGroupId()));
            List<PmsAttrEntity> pmsAttrs = relations.stream().map(relation -> {
                PmsAttrEntity attrEntity = pmsAttrDao.selectById(relation.getAttrId());
                return attrEntity;
            }).collect(Collectors.toList());
           attrGroupWithAttrsVo.setAttrs(pmsAttrs);
            return attrGroupWithAttrsVo;
        }).collect(Collectors.toList());

        return attrs;
    }

}